Tarjan's SCC Algorithm Algorithm
Tarjan's Strongly Connected Components (SCC) Algorithm is an efficient graph theory algorithm used to identify and partition the strongly connected components within a directed graph. It was developed by Robert Tarjan in 1972 and is based on the depth-first search (DFS) traversal technique. The algorithm operates by performing a DFS on the input graph while maintaining a stack data structure to keep track of the visited nodes. Nodes are assigned both a unique index and a low-link value, which helps determine the connectivity among the nodes in the graph. When the DFS finishes traversing a subtree and backtracks, the algorithm checks if the current node is the root of a strongly connected component. If it is, the SCC is formed by popping the nodes from the stack until the current node is reached.
The key advantage of Tarjan's algorithm is its linear time complexity, which allows it to efficiently process large graphs. The time complexity of the algorithm is O(V + E), where V is the number of vertices and E is the number of edges in the graph. Furthermore, the algorithm has a relatively low memory overhead, as it only requires an additional stack to store the visited nodes during the DFS traversal. This combination of speed and memory efficiency makes Tarjan's SCC Algorithm a popular choice for practical applications involving graph analysis, such as network flow, circuit design, and program optimization.
/*
Petar 'PetarV' Velickovic
Algorithm: Tarjan's SCC Algorithm
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <complex>
#define MAX_N 20001
#define INF 987654321
using namespace std;
typedef long long lld;
int n, m;
struct Node
{
vector<int> adj;
};
Node graf[MAX_N];
stack<int> Stack;
bool onStack[MAX_N];
int Indices;
int Index[MAX_N];
int LowLink[MAX_N];
int component[MAX_N];
int numComponents;
//Tarjanov algoritam za racunanje jako povezanih komponenti datog usmerenog grafa
//Slozenost: O(V + E)
void tarjanDFS(int i)
{
Index[i] = ++Indices;
LowLink[i] = Indices;
Stack.push(i); onStack[i] = true;
for (int j=0;j<graf[i].adj.size();j++)
{
int w = graf[i].adj[j];
if (Index[w] == 0)
{
tarjanDFS(w);
LowLink[i] = min(LowLink[i], LowLink[w]);
}
else if (onStack[w])
{
LowLink[i] = min(LowLink[i], Index[w]);
}
}
if (LowLink[i] == Index[i])
{
int w = 0;
do
{
w = Stack.top(); Stack.pop();
component[w] = numComponents;
onStack[w]=false;
} while (i != w && !Stack.empty());
numComponents++;
}
}
void Tarjan()
{
Indices = 0;
while (!Stack.empty()) Stack.pop();
for (int i=n;i>0;i--) onStack[i] = LowLink[i] = Index[i] = 0;
numComponents = 0;
for (int i=n;i>0;i--) if (Index[i] == 0) tarjanDFS(i);
}
int main()
{
n = 8, m = 14;
graf[0].adj.push_back(1);
graf[1].adj.push_back(2);
graf[1].adj.push_back(4);
graf[1].adj.push_back(5);
graf[2].adj.push_back(3);
graf[2].adj.push_back(6);
graf[3].adj.push_back(2);
graf[3].adj.push_back(7);
graf[4].adj.push_back(5);
graf[5].adj.push_back(6);
graf[6].adj.push_back(5);
graf[7].adj.push_back(3);
graf[7].adj.push_back(6);
Tarjan();
printf("%d\n",numComponents);
return 0;
}